package com.audaque.cloud.iqs.dbs.service.impl;

import com.audaque.cloud.iqs.dbs.enums.DBDataTypeEnum;
import com.audaque.cloud.iqs.dbs.service.DsHandler;
import com.audaque.cloud.iqs.dbs.vo.ColumnInfo;
import com.audaque.cloud.iqs.dbs.vo.DateVo;
import com.audaque.cloud.iqs.dbs.vo.TableInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * mysql
 * @author HuangHL
 * @date 2022-10-17 16:50:29
 */
public class DsHandlerMysql implements DsHandler {
    @Override
    public boolean canHander(String driveClass) {
        return driveClass.contains("mysql");
    }

    @Override
    public String getTablesSql(String scheme,String user) {
        return "SELECT\n" + "    TABLE_NAME,\n" + "    TABLE_COMMENT\n" + "FROM\n" + "    information_schema.`TABLES`\n"
                + "WHERE\n" + "    TABLE_SCHEMA = '"+scheme+"'";
    }

    @Override
    public String getColumnsSql(String scheme,String user,String tableName) {
        return "SELECT\n" + "    *\n" + "FROM\n" + "    information_schema.`COLUMNS` \n" + "WHERE\n"
                + "    TABLE_SCHEMA = '"+scheme+"'\n" + "    and TABLE_NAME ='"+tableName+"'";
    }

    @Override
    public String getSchema(String schema,String database,String username) {
        return database;
    }

    @Override
    public List<TableInfo> listToTables(List<Map<String, Object>> list) {
        List<TableInfo> res = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (Map<String, Object> map:list) {
                String tableName = null;
                String tableDesc = null;
                if(map.get("TABLE_NAME") != null) {
                    tableName = map.get("TABLE_NAME").toString();
                }
                if(map.get("TABLE_COMMENT") != null) {
                    tableDesc = map.get("TABLE_COMMENT").toString();
                }
                TableInfo tableInfo = new TableInfo(tableName,tableDesc);
                res.add(tableInfo);
            }
        }
        return res;
    }

    @Override
    public List<ColumnInfo> listToColumns(List<Map<String, Object>> list,String tableName) {
        List<ColumnInfo> res = new ArrayList<>();
        for (Map<String, Object> map:list) {
            String colName = null;
            String colDesc = null;
            String dataType = null;
            String length = null;
            String po = null;
            String key = "0";
            String isIfNull = "0";
            if(map.get("COLUMN_NAME") != null) {
                colName = map.get("COLUMN_NAME").toString();
            }
            if(map.get("COLUMN_COMMENT") != null) {
                colDesc = map.get("COLUMN_COMMENT").toString();
            }
            if(map.get("DATA_TYPE") != null) {
                dataType = map.get("DATA_TYPE").toString();
            }
            if(map.get("COLUMN_TYPE") != null) {
                String typeLength = map.get("COLUMN_TYPE").toString();
                if(typeLength.contains("(")) {
                    String lp = typeLength.substring(typeLength.indexOf("(")+1,typeLength.indexOf(")"));
                    String[] lpArr = lp.split(",");
                    if(lpArr.length == 1) {
                        length = lpArr[0];
                    }
                    if(lpArr.length == 2) {
                        length = lpArr[0];
                        po = lpArr[1];
                    }
                }
            }
            if(map.get("COLUMN_KEY") != null) {
                String pk = map.get("COLUMN_KEY").toString();
                if("PRI".equals(pk)){
                    key = "1";
                }
            }
            if(map.get("IS_NULLABLE") != null) {
                String isNull = map.get("IS_NULLABLE").toString();
                if("YES".equals(isNull)){
                    isIfNull = "1";
                }
                if("NO".equals(isNull)){
                    isIfNull = "0";
                }
            }
            ColumnInfo columnInfo = new ColumnInfo();
            columnInfo.setTableName(tableName);
            columnInfo.setColName(colName);
            columnInfo.setColDesc(colDesc);
            columnInfo.setColType(dataType);
            columnInfo.setColDataType(DBDataTypeEnum.OTHER.getCode());
            if(dataType!=null){
                if(dataType.toUpperCase().contains("INT")){
                    columnInfo.setColDataType(DBDataTypeEnum.NUNBER.getCode());
                }
                if(dataType.toUpperCase().contains("FLOAT")){
                    columnInfo.setColDataType(DBDataTypeEnum.NUNBER.getCode());
                }
                if(dataType.toUpperCase().contains("DOUBLE")){
                    columnInfo.setColDataType(DBDataTypeEnum.NUNBER.getCode());
                }
                if(dataType.toUpperCase().contains("DECIMAL")){
                    columnInfo.setColDataType(DBDataTypeEnum.NUNBER.getCode());
                }
                if(dataType.toUpperCase().contains("HAR") ||dataType.toUpperCase().contains("TEXT")
                        ||dataType.toUpperCase().contains("BLOB")){
                    columnInfo.setColDataType(DBDataTypeEnum.CHAR.getCode());
                }
                if(dataType.toUpperCase().contains("DATE") ||dataType.toUpperCase().contains("TIME")){
                    columnInfo.setColDataType(DBDataTypeEnum.DATATIME.getCode());
                }
            }
            if(length!=null) {
                columnInfo.setColLength(Long.valueOf(length));
            }
            if(po!=null) {
                columnInfo.setColPrecision(Integer.valueOf(po));
            }
            columnInfo.setKeyFlag(key);
            columnInfo.setNullable(isIfNull);
            if(map.get("ORDINAL_POSITION") != null) {
                String ordinalPosition = map.get("ORDINAL_POSITION").toString();
                columnInfo.setColSeq(Integer.valueOf(ordinalPosition));
            }
            res.add(columnInfo);
        }
        return res;
    }

    @Override
    public String getPage(String sql,int pageNo,int pageSize) {
        int offset = (pageNo-1)*pageSize;
        String mysql = sql+" limit "+offset+","+pageSize;
        return mysql;
    }

    @Override
    public String getDateWhereSql(DateVo dateVo) {
        return "date_format("+dateVo.getCol()+" ,'%Y-%m-%d %H:%i:%S')"+dateVo.getWhereTypeStr()+"'"+dateVo.getVal()+"'";
    }

    @Override
    public String prosessAs(String sql) {
        return sql;
    }


    @Override
    public String sqlSpilit() {
        return "`";
    }
}
